home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / Interfaces&Libraries / Universal / Interfaces / AIncludes / PEFBinaryFormat.a < prev    next >
Encoding:
Text File  |  1998-08-17  |  37.7 KB  |  737 lines  |  [TEXT/MPS ]

  1. ;
  2. ;    File:        PEFBinaryFormat.a
  3. ;
  4. ;    Contains:    PEF Types and Macros
  5. ;
  6. ;    Version:    Technology:    Master Interfaces
  7. ;                Release:    Universal Interfaces 3.2
  8. ;
  9. ;    Copyright:    © 1993-1998, 1998 by Apple Computer, Inc., all rights reserved.
  10. ;
  11. ;    Bugs?:        For bug reports, consult the following page on
  12. ;                the World Wide Web:
  13. ;
  14. ;                    http://developer.apple.com/bugreporter/
  15. ;
  16. ;
  17.  
  18.  
  19.     IF &TYPE('__PEFBINARYFORMAT__') = 'UNDEFINED' THEN
  20. __PEFBINARYFORMAT__ SET 1
  21.  
  22.     IF &TYPE('__MACTYPES__') = 'UNDEFINED' THEN
  23.     include 'MacTypes.a'
  24.     ENDIF
  25.  
  26.  
  27. ;  -------------------------------------------------------------------------------------------- 
  28. ;  Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    
  29. ;  10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        
  30. ;  packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        
  31. ;  ensure consistent treatment across compilers.                                                
  32.  
  33. ;  ======================================================================================== 
  34. ;  Overall Structure 
  35. ;  ================= 
  36.  
  37. ;  -------------------------------------------------------------------------------------------- 
  38. ;  This header contains a complete set of types and macros for dealing with the PEF executable    
  39. ;  format.  While some description is provided, this header is not meant as a primary source    
  40. ;  of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    
  41. ;  Runtime Architectures book.  This header is primarily a physical format description.  Thus    
  42. ;  it depends on as few other headers as possible and structure fields have obvious sizes.        
  43. ;                                                                                                  
  44. ;  The physical storage for a PEF executable is known as a "container".  This refers to just    
  45. ;  the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    
  46. ;  data fork, that one data fork has five containers within it.                                    
  47. ;                                                                                                  
  48. ;  A PEF container consists of an overall header, followed by one or more section headers,        
  49. ;  followed by the section name table, followed by the contents for the sections.  Some kinds    
  50. ;  of sections have specific internal representation.  The "loader" section is the most common    
  51. ;  of these special sections.  It contains information on the exports, imports, and runtime        
  52. ;  relocations required to prepare the executable.  PEF containers are self contained, all        
  53. ;  portions are located via relative offsets.                                                    
  54. ;                                                                                                  
  55. ;                                                                                                  
  56. ;             +-------------------------------+                                                    
  57. ;             |        Container Header        |    40 bytes                                        
  58. ;             +-------------------------------+                                                    
  59. ;             |        Section 0 header        |    28 bytes each                                    
  60. ;             |...............................|                                                    
  61. ;             |            - - - -                |                                                    
  62. ;             |...............................|                                                    
  63. ;             |        Section n-1 header        |                                                    
  64. ;             +-------------------------------+                                                    
  65. ;             |        Section Name Table        |                                                    
  66. ;             +-------------------------------+                                                    
  67. ;             |        Section x raw data        |                                                    
  68. ;             +-------------------------------+                                                    
  69. ;              |            - - - -                |                                                    
  70. ;             +-------------------------------+                                                    
  71. ;             |        Section y raw data        |                                                    
  72. ;             +-------------------------------+                                                    
  73. ;                                                                                                  
  74. ;                                                                                                  
  75. ;  The sections are implicitly numbered from 0 to n according to the order of their headers.    
  76. ;  The headers of the instantiated sections must precede those of the non-instantiated            
  77. ;  sections.  The ordering of the raw data is independent of the section header ordering.        
  78. ;  Each section header contains the offset for that section's raw data.                            
  79.  
  80. ;  =========================================================================================== 
  81. ;  Container Header 
  82. ;  ================ 
  83.  
  84. PEFContainerHeader        RECORD 0
  85. tag1                     ds.l    1                ; offset: $0 (0)        ;  Must contain 'Joy!'.
  86. tag2                     ds.l    1                ; offset: $4 (4)        ;  Must contain 'peff'.  (Yes, with two 'f's.)
  87. architecture             ds.l    1                ; offset: $8 (8)        ;  The ISA for code sections.  Constants in CodeFragments.h.
  88. formatVersion             ds.l    1                ; offset: $C (12)        ;  The physical format version.
  89. dateTimeStamp             ds.l    1                ; offset: $10 (16)        ;  Macintosh format creation/modification stamp.
  90. oldDefVersion             ds.l    1                ; offset: $14 (20)        ;  Old definition version number for the code fragment.
  91. oldImpVersion             ds.l    1                ; offset: $18 (24)        ;  Old implementation version number for the code fragment.
  92. currentVersion             ds.l    1                ; offset: $1C (28)        ;  Current version number for the code fragment.
  93. sectionCount             ds.w    1                ; offset: $20 (32)        ;  Total number of section headers that follow.
  94. instSectionCount         ds.w    1                ; offset: $22 (34)        ;  Number of instantiated sections.
  95. reservedA                 ds.l    1                ; offset: $24 (36)        ;  Reserved, must be written as zero.
  96. sizeof                     EQU *                    ; size:   $28 (40)
  97.                         ENDR
  98.  
  99. kPEFTag1                        EQU        'Joy!'                ; For non-Apple compilers: 0x4A6F7921.
  100. kPEFTag2                        EQU        'peff'                ; For non-Apple compilers: 0x70656666.
  101. kPEFVersion                        EQU        $00000001
  102.  
  103.  
  104. kPEFFirstSectionHeaderOffset    EQU        40
  105.  
  106. ;  =========================================================================================== 
  107. ;  Section Headers 
  108. ;  =============== 
  109.  
  110. PEFSectionHeader        RECORD 0
  111. nameOffset                 ds.l    1                ; offset: $0 (0)        ;  Offset of name within the section name table, -1 => none.
  112. defaultAddress             ds.l    1                ; offset: $4 (4)        ;  Default address, affects relocations.
  113. totalLength                 ds.l    1                ; offset: $8 (8)        ;  Fully expanded size in bytes of the section contents.
  114. unpackedLength             ds.l    1                ; offset: $C (12)        ;  Size in bytes of the "initialized" part of the contents.
  115. containerLength             ds.l    1                ; offset: $10 (16)        ;  Size in bytes of the raw data in the container.
  116. containerOffset             ds.l    1                ; offset: $14 (20)        ;  Offset of section's raw data.
  117. sectionKind                 ds.b    1                ; offset: $18 (24)        ;  Kind of section contents/usage.
  118. shareKind                 ds.b    1                ; offset: $19 (25)        ;  Sharing level, if a writeable section.
  119. alignment                 ds.b    1                ; offset: $1A (26)        ;  Preferred alignment, expressed as log 2.
  120. reservedA                 ds.b    1                ; offset: $1B (27)        ;  Reserved, must be zero.
  121. sizeof                     EQU *                    ; size:   $1C (28)
  122.                         ENDR
  123.  
  124.                                                             ; Values for the sectionKind field.
  125.                                                             ;    Section kind values for instantiated sections.
  126. kPEFCodeSection                    EQU        0                    ; Code, presumed pure & position independent.
  127. kPEFUnpackedDataSection            EQU        1                    ; Unpacked writeable data.
  128. kPEFPackedDataSection            EQU        2                    ; Packed writeable data.
  129. kPEFConstantSection                EQU        3                    ; Read-only data.
  130. kPEFExecDataSection                EQU        6                    ; Intermixed code and writeable data.
  131.                                                             ; Section kind values for non-instantiated sections.
  132. kPEFLoaderSection                EQU        4                    ; Loader tables.
  133. kPEFDebugSection                EQU        5                    ; Reserved for future use.
  134. kPEFExceptionSection            EQU        7                    ; Reserved for future use.
  135. kPEFTracebackSection            EQU        8                    ; Reserved for future use.
  136.  
  137.  
  138.                                                             ; Values for the shareKind field.
  139. kPEFProcessShare                EQU        1                    ; Shared within a single process.
  140. kPEFGlobalShare                    EQU        4                    ; Shared across the entire system.
  141. kPEFProtectedShare                EQU        5                    ; Readable across the entire system, writeable only to privileged code.
  142.  
  143. ;  =========================================================================================== 
  144. ;  Packed Data Contents 
  145. ;  ==================== 
  146.  
  147. ;  -------------------------------------------------------------------------------------------- 
  148. ;  The raw contents of a packed data section are a sequence of byte codes.  The basic format    
  149. ;  has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        
  150. ;  counts larger than 31, and to contain a second or third count.  Further additional bytes        
  151. ;  contain actual data values to transfer.                                                        
  152. ;                                                                                                  
  153. ;  All counts are represented in a variable length manner.  A zero in the initial 5 bit count    
  154. ;  indicates the actual value follows.  In this case, and for the second and third counts, the    
  155. ;  count is represented as a variable length sequence of bytes.  The bytes are stored in big    
  156. ;  endian manner, most significant part first.  The high order bit is set in all but the last    
  157. ;  byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    
  158. ;  low order 7 bits of the next byte.                                                            
  159.  
  160.  
  161.                                                             ; The packed data opcodes.
  162. kPEFPkDataZero                    EQU        0                    ; Zero fill "count" bytes.
  163. kPEFPkDataBlock                    EQU        1                    ; Block copy "count" bytes.
  164. kPEFPkDataRepeat                EQU        2                    ; Repeat "count" bytes "count2"+1 times.
  165. kPEFPkDataRepeatBlock            EQU        3                    ; Interleaved repeated and unique data.
  166. kPEFPkDataRepeatZero            EQU        4                    ; Interleaved zero and unique data.
  167.  
  168.  
  169. kPEFPkDataOpcodeShift            EQU        5
  170. kPEFPkDataCount5Mask            EQU        $1F
  171. kPEFPkDataMaxCount5                EQU        31
  172. kPEFPkDataVCountShift            EQU        7
  173. kPEFPkDataVCountMask            EQU        $7F
  174. kPEFPkDataVCountEndMask            EQU        $80
  175.  
  176.  
  177. ;  -------------------------------------------------------------------------------------------- 
  178. ;  The following code snippet can be used to input a variable length count.                        
  179. ;                                                                                                  
  180. ;         count = 0;                                                                                
  181. ;         do {                                                                                    
  182. ;             byte = *bytePtr++;                                                                    
  183. ;             count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            
  184. ;         } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        
  185. ;                                                                                                  
  186. ;  The following code snippet can be used to output a variable length count to a byte array.    
  187. ;  This is more complex than the input code because the chunks are output in big endian order.    
  188. ;  Think about handling values like 0 or 0x030000.                                                
  189. ;                                                                                                  
  190. ;         count = 1;.                                                                                
  191. ;         tempValue = value >> kPEFPkDataCountShift;                                                
  192. ;         while ( tempValue != 0 ) {                                                                
  193. ;             count += 1;                                                                            
  194. ;             tempValue = tempValue >> kPEFPkDataCountShift;                                        
  195. ;         }                                                                                        
  196. ;                                                                                                  
  197. ;         bytePtr += count;                                                                        
  198. ;         tempPtr = bytePtr - 1;                                                                    
  199. ;         *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        
  200. ;         for ( count -= 1; count != 0; count -= 1 ) {                                            
  201. ;             value = value >> kPEFPkDataCountShift;                                                
  202. ;             *tempPtr-- = value | kPEFPkDataCountEndMask;                                        
  203. ;         }                                                                                        
  204.  
  205. ;  =========================================================================================== 
  206. ;  Loader Section 
  207. ;  ============== 
  208.  
  209. ;  -------------------------------------------------------------------------------------------- 
  210. ;  The loader section contains information needed to prepare the code fragment for execution.    
  211. ;  This includes this fragment's exports, the import libraries and the imported symbols from    
  212. ;  each library, and the relocations for the writeable sections.                                
  213. ;                                                                                                  
  214. ;             +-----------------------------------+                <-- containerOffset --------+    
  215. ;             |        Loader Info Header            |    56 bytes                                |    
  216. ;             |-----------------------------------|                                            |    
  217. ;             |        Imported Library 0            |    24 bytes each                            |    
  218. ;             |...................................|                                            |    
  219. ;             |            - - -                    |                                            |    
  220. ;             |...................................|                                            |    
  221. ;             |        Imported Library l-1        |                                            |    
  222. ;             |-----------------------------------|                                            |    
  223. ;             |        Imported Symbol 0            |    4 bytes each                            |    
  224. ;             |...................................|                                            |    
  225. ;             |            - - -                    |                                            |    
  226. ;             |...................................|                                            |    
  227. ;             |         Imported Symbol i-1            |                                            |    
  228. ;             |-----------------------------------|                                            |    
  229. ;             |        Relocation Header 0            |    12 bytes each                            |    
  230. ;             |...................................|                                            |    
  231. ;             |            - - -                    |                                            |    
  232. ;             |...................................|                                            |    
  233. ;             |        Relocation Header r-1        |                                            |    
  234. ;             |-----------------------------------|                <-- + relocInstrOffset -----|    
  235. ;             |        Relocation Instructions        |                                            |    
  236. ;             |-----------------------------------|                <-- + loaderStringsOffset --|    
  237. ;             |        Loader String Table            |                                            |    
  238. ;             |-----------------------------------|                <-- + exportHashOffset -----+    
  239. ;             |        Export Hash Slot 0            |    4 bytes each                                
  240. ;             |...................................|                                                
  241. ;             |            - - -                    |                                                
  242. ;             |...................................|                                                
  243. ;             |         Export Hash Slot h-1        |                                                
  244. ;             |-----------------------------------|                                                
  245. ;             |        Export Symbol Key 0            |    4 bytes each                                
  246. ;             |...................................|                                                
  247. ;             |            - - -                    |                                                
  248. ;             |...................................|                                                
  249. ;             |        Export Symbol Key e-1        |                                                
  250. ;             |-----------------------------------|                                                
  251. ;             |        Export Symbol 0                |    10 bytes each                                
  252. ;             |...................................|                                                
  253. ;             |            - - -                    |                                                
  254. ;             |...................................|                                                
  255. ;             |        Export Symbol e-1            |                                                
  256. ;             +-----------------------------------+                                                
  257.  
  258. PEFLoaderInfoHeader        RECORD 0
  259. mainSection                 ds.l    1                ; offset: $0 (0)        ;  Section containing the main symbol, -1 => none.
  260. mainOffset                 ds.l    1                ; offset: $4 (4)        ;  Offset of main symbol.
  261. initSection                 ds.l    1                ; offset: $8 (8)        ;  Section containing the init routine's TVector, -1 => none.
  262. initOffset                 ds.l    1                ; offset: $C (12)        ;  Offset of the init routine's TVector.
  263. termSection                 ds.l    1                ; offset: $10 (16)        ;  Section containing the term routine's TVector, -1 => none.
  264. termOffset                 ds.l    1                ; offset: $14 (20)        ;  Offset of the term routine's TVector.
  265. importedLibraryCount     ds.l    1                ; offset: $18 (24)        ;  Number of imported libraries.  ('l')
  266. totalImportedSymbolCount  ds.l    1                ; offset: $1C (28)        ;  Total number of imported symbols.  ('i')
  267. relocSectionCount         ds.l    1                ; offset: $20 (32)        ;  Number of sections with relocations.  ('r')
  268. relocInstrOffset         ds.l    1                ; offset: $24 (36)        ;  Offset of the relocation instructions.
  269. loaderStringsOffset         ds.l    1                ; offset: $28 (40)        ;  Offset of the loader string table.
  270. exportHashOffset         ds.l    1                ; offset: $2C (44)        ;  Offset of the export hash table.
  271. exportHashTablePower     ds.l    1                ; offset: $30 (48)        ;  Export hash table size as log 2.  (Log2('h'))
  272. exportedSymbolCount         ds.l    1                ; offset: $34 (52)        ;  Number of exported symbols.  ('e')
  273. sizeof                     EQU *                    ; size:   $38 (56)
  274.                         ENDR
  275. ;  =========================================================================================== 
  276. ;  Imported Libraries 
  277. ;  ------------------ 
  278. PEFImportedLibrary        RECORD 0
  279. nameOffset                 ds.l    1                ; offset: $0 (0)        ;  Loader string table offset of library's name.
  280. oldImpVersion             ds.l    1                ; offset: $4 (4)        ;  Oldest compatible implementation version.
  281. currentVersion             ds.l    1                ; offset: $8 (8)        ;  Current version at build time.
  282. importedSymbolCount         ds.l    1                ; offset: $C (12)        ;  Imported symbol count for this library.
  283. firstImportedSymbol         ds.l    1                ; offset: $10 (16)        ;  Index of first imported symbol from this library.
  284. options                     ds.b    1                ; offset: $14 (20)        ;  Option bits for this library.
  285. reservedA                 ds.b    1                ; offset: $15 (21)        ;  Reserved, must be zero.
  286. reservedB                 ds.w    1                ; offset: $16 (22)        ;  Reserved, must be zero.
  287. sizeof                     EQU *                    ; size:   $18 (24)
  288.                         ENDR
  289.  
  290.                                                             ; Bits for the PEFImportedLibrary options field.
  291. kPEFWeakImportLibMask            EQU        $40                    ; The imported library is allowed to be missing.
  292. kPEFInitLibBeforeMask            EQU        $80                    ; The imported library must be initialized first.
  293.  
  294. ;  =========================================================================================== 
  295. ;  Imported Symbols 
  296. ;  ---------------- 
  297.  
  298. ;  -------------------------------------------------------------------------------------------- 
  299. ;  The PEFImportedSymbol type has the following bit field layout.                                
  300. ;                                                                                                  
  301. ;                                                                        3                        
  302. ;          0             7 8                                             1                        
  303. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  304. ;       | symbol class  | offset of symbol name in loader string table  |                        
  305. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  306. ;         |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        
  307.  
  308. PEFImportedSymbol        RECORD 0
  309. classAndName             ds.l    1                ; offset: $0 (0)
  310. sizeof                     EQU *                    ; size:   $4 (4)
  311.                         ENDR
  312.  
  313. kPEFImpSymClassShift            EQU        24
  314. kPEFImpSymNameOffsetMask        EQU        $00FFFFFF
  315. kPEFImpSymMaxNameOffset            EQU        $00FFFFFF            ; 16,777,215
  316.  
  317.  
  318.                                                             ; Imported and exported symbol classes.
  319. kPEFCodeSymbol                    EQU        $00
  320. kPEFDataSymbol                    EQU        $01
  321. kPEFTVectorSymbol                EQU        $02
  322. kPEFTOCSymbol                    EQU        $03
  323. kPEFGlueSymbol                    EQU        $04
  324. kPEFUndefinedSymbol                EQU        $0F
  325. kPEFWeakImportSymMask            EQU        $80
  326.  
  327. ;  =========================================================================================== 
  328. ;  Exported Symbol Hash Table 
  329. ;  -------------------------- 
  330.  
  331. ;  -------------------------------------------------------------------------------------------- 
  332. ;  Exported symbols are described in four parts, optimized for speed of lookup.  These parts    
  333. ;  are the "export hash table", the "export key table", the "export symbol table", and the        
  334. ;  "export name table".  Overall they contain a flattened representation of a fairly normal        
  335. ;  hashed symbol table.                                                                            
  336. ;                                                                                                 
  337. ;  The export hash table is an array of small fixed size elements.  The number of elements is    
  338. ;  a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    
  339. ;  Each hash slot contains a count of the number of exported symbols that map to this slot and    
  340. ;  the index of the first of those symbols in the key and symbol tables.  Of course some hash    
  341. ;  slots will have a zero count.                                                                
  342. ;                                                                                                 
  343. ;  The key and symbol tables are also arrays of fixed size elements, one for each exported        
  344. ;  symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        
  345. ;  slot are contiguous.  The key table contains just the full 32 bit hash word for each            
  346. ;  exported symbol.  The symbol table contains the offset of the symbol's name in the string    
  347. ;  table and other information about the exported symbol.                                        
  348. ;                                                                                                 
  349. ;  To look up an export you take the hashword and compute the hash slot index.  You then scan    
  350. ;  the indicated portion of the key table for matching hashwords.  If a hashword matches, you    
  351. ;  look at the corresponding symbol table entry to find the full symbol name.  If the names        
  352. ;  match the symbol is found.                                                                    
  353.  
  354. ;  -------------------------------------------------------------------------------------------- 
  355. ;  The following function may be used to compute the hash table size.  Signed values are used    
  356. ;  just to avoid potential code generation overhead for unsigned division.                        
  357. ;                                                                                                  
  358. ;         UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            
  359. ;         {                                                                                        
  360. ;             SInt32    exponent;                                                                    
  361. ;                                                                                                  
  362. ;             const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    
  363. ;             const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    
  364. ;                                                                                                  
  365. ;             for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    
  366. ;                 if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                
  367. ;             }                                                                                    
  368. ;                                                                                                  
  369. ;             return exponent;                                                                    
  370. ;                                                                                                  
  371. ;         }    // PEFComputeHashTableExponent ()                                                    
  372.  
  373. ;  -------------------------------------------------------------------------------------------- 
  374. ;  The PEFExportedSymbolHashSlot type has the following bit field layout.                        
  375. ;                                                                                                  
  376. ;                                    1 1                                 3                        
  377. ;          0                         3 4                                 1                        
  378. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  379. ;         | symbol count              | index of first export key         |                        
  380. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  381. ;         |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        
  382.  
  383. PEFExportedSymbolHashSlot RECORD 0
  384. countAndStart             ds.l    1                ; offset: $0 (0)
  385. sizeof                     EQU *                    ; size:   $4 (4)
  386.                         ENDR
  387.  
  388. kPEFHashSlotSymCountShift        EQU        18
  389. kPEFHashSlotFirstKeyMask        EQU        $0003FFFF
  390. kPEFHashSlotMaxSymbolCount        EQU        $00003FFF            ;  16,383
  391. kPEFHashSlotMaxKeyIndex            EQU        $0003FFFF            ; 262,143
  392.  
  393. ;  =========================================================================================== 
  394. ;  Exported Symbol Hash Key 
  395. ;  ------------------------ 
  396.  
  397. PEFSplitHashWord        RECORD 0
  398. nameLength                 ds.w    1                ; offset: $0 (0)
  399. hashValue                 ds.w    1                ; offset: $2 (2)
  400. sizeof                     EQU *                    ; size:   $4 (4)
  401.                         ENDR
  402. PEFExportedSymbolKey    RECORD 0
  403. fullHashWord             ds.l    1                ; offset: $0 (0)
  404.                          ORG 0
  405. splitHashWord             ds        PEFSplitHashWord ; offset: $0 (0)
  406. sizeof                     EQU *                    ; size:   $4 (4)
  407.                         ENDR
  408.  
  409. kPEFHashLengthShift                EQU        16
  410. kPEFHashValueMask                EQU        $0000FFFF
  411. kPEFHashMaxLength                EQU        $0000FFFF            ; 65,535
  412.  
  413. ;  ---------------------------------------------------------------------------------------------------- 
  414. ;  The following function computes the full 32 bit hash word.                                            
  415. ;                                                                                                          
  416. ;         UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    
  417. ;                                       UInt32    nameLength )    // ! The text may be zero terminated.    
  418. ;         {                                                                                                
  419. ;             BytePtr    charPtr        = nameText;                                                                
  420. ;             SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                
  421. ;             UInt32    length        = 0;                                                                    
  422. ;             UInt32    limit;                                                                                
  423. ;             UInt32    result;                                                                                
  424. ;             UInt8    currChar;                                                                            
  425. ;                                                                                                          
  426. ;             #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    
  427. ;                                                                                                          
  428. ;             for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            
  429. ;                 currChar = *charPtr++;                                                                    
  430. ;                 if ( currChar == NULL ) break;                                                            
  431. ;                 length += 1;                                                                            
  432. ;                 hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        
  433. ;             }                                                                                            
  434. ;                                                                                                          
  435. ;             result    = (length << kPEFHashLengthShift) |                                                    
  436. ;                       ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    
  437. ;                                                                                                          
  438. ;             return result;                                                                                
  439. ;                                                                                                          
  440. ;         }    // PEFComputeHashWord ()                                                                    
  441.  
  442. ;  =========================================================================================== 
  443. ;  Exported Symbols 
  444. ;  ---------------- 
  445.  
  446. PEFExportedSymbol        RECORD 0
  447. ;  ! This structure is 10 bytes long and arrays are packed.
  448. classAndName             ds.l    1                ; offset: $0 (0)        ;  A combination of class and name offset.
  449. symbolValue                 ds.l    1                ; offset: $4 (4)        ;  Typically the symbol's offset within a section.
  450. sectionIndex             ds.w    1                ; offset: $8 (8)        ;  The index of the section, or pseudo-section, for the symbol.
  451. sizeof                     EQU *                    ; size:   $A (10)
  452.                         ENDR
  453. ;  -------------------------------------------------------------------------------------------- 
  454. ;  The classAndName field of the PEFExportedSymbol type has the following bit field layout.        
  455. ;                                                                                                  
  456. ;                                                                        3                        
  457. ;          0             7 8                                             1                        
  458. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  459. ;       | symbol class  | offset of symbol name in loader string table  |                        
  460. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
  461. ;         |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        
  462.  
  463.  
  464. kPEFExpSymClassShift            EQU        24
  465. kPEFExpSymNameOffsetMask        EQU        $00FFFFFF
  466. kPEFExpSymMaxNameOffset            EQU        $00FFFFFF            ; 16,777,215
  467.  
  468.  
  469.                                                             ; Negative section indices indicate pseudo-sections.
  470. kPEFAbsoluteExport                EQU        -2                    ; The symbol value is an absolute address.
  471. kPEFReexportedImport            EQU        -3                    ; The symbol value is the index of a reexported import.
  472.  
  473. ;  =========================================================================================== 
  474. ;  Loader Relocations 
  475. ;  ================== 
  476.  
  477. ;  -------------------------------------------------------------------------------------------- 
  478. ;  The relocations for a section are defined by a sequence of instructions for an abstract        
  479. ;  machine that is specifically geared to performing relocations commonly needed for the "CFM"    
  480. ;  code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    
  481. ;  just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    
  482. ;  the operands in the first chunk, with other operands in following chunks.                    
  483. ;                                                                                                 
  484. ;  ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk.  The    
  485. ;  ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc.            
  486.  
  487. ; typedef UInt16                         PEFRelocChunk
  488.  
  489. PEFLoaderRelocationHeader RECORD 0
  490. sectionIndex             ds.w    1                ; offset: $0 (0)        ;  Index of the section to be fixed up.
  491. reservedA                 ds.w    1                ; offset: $2 (2)        ;  Reserved, must be zero.
  492. relocCount                 ds.l    1                ; offset: $4 (4)        ;  Number of 16 bit relocation chunks.
  493. firstRelocOffset         ds.l    1                ; offset: $8 (8)        ;  Offset of first relocation instruction.
  494. sizeof                     EQU *                    ; size:   $C (12)
  495.                         ENDR
  496. ;  -------------------------------------------------------------------------------------------- 
  497. ;  ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        
  498. ;  ! total number of bytes of relocation instructions.  While most relocation instructions are    
  499. ;  ! 16 bits long, some are longer so the number of complete relocation instructions may be        
  500. ;  ! less than the relocCount value.                                                            
  501.  
  502. ;  ------------------------------------------------------------------------------------ 
  503. ;  The PEFRelocField macro is a utility for extracting relocation instruction fields.    
  504.  
  505. ;  =========================================================================================== 
  506. ;  Basic Relocation Opcodes 
  507. ;  ------------------------ 
  508. ;  -------------------------------------------------------------------------------------------- 
  509. ;  The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    
  510. ;  are defined in terms of the most significant 7 bits of the first instruction chunk.  An        
  511. ;  instruction is decoded by using the most significant 7 bits as an index into the opcode        
  512. ;  table, which in turn contains appropriately masked forms of the most significant 7 bits.        
  513. ;  The macro PEFRelocBasicOpcode assumes a declaration of the form.                                
  514. ;                                                                                                  
  515. ;         UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    
  516.  
  517.  
  518. kPEFRelocBasicOpcodeRange        EQU        128
  519.  
  520. ;  -------------------------------------------------------------------------------------------- 
  521. ;  The relocation opcodes, clustered by major and minor groups.  The instructions within a        
  522. ;  cluster all have the same bit field layout.  The enumeration values use the high order 7        
  523. ;  bits of the relocation instruction.  Unused low order bits are set to zero.                    
  524.  
  525. kPEFRelocBySectDWithSkip        EQU        $00                    ; Binary: 00x_xxxx
  526. kPEFRelocBySectC                EQU        $20                    ; Binary: 010_0000, group is "RelocRun"
  527. kPEFRelocBySectD                EQU        $21                    ; Binary: 010_0001
  528. kPEFRelocTVector12                EQU        $22                    ; Binary: 010_0010
  529. kPEFRelocTVector8                EQU        $23                    ; Binary: 010_0011
  530. kPEFRelocVTable8                EQU        $24                    ; Binary: 010_0100
  531. kPEFRelocImportRun                EQU        $25                    ; Binary: 010_0101
  532. kPEFRelocSmByImport                EQU        $30                    ; Binary: 011_0000, group is "RelocSmIndex"
  533. kPEFRelocSmSetSectC                EQU        $31                    ; Binary: 011_0001
  534. kPEFRelocSmSetSectD                EQU        $32                    ; Binary: 011_0010
  535. kPEFRelocSmBySection            EQU        $33                    ; Binary: 011_0011
  536. kPEFRelocIncrPosition            EQU        $40                    ; Binary: 100_0xxx
  537. kPEFRelocSmRepeat                EQU        $48                    ; Binary: 100_1xxx
  538. kPEFRelocSetPosition            EQU        $50                    ; Binary: 101_000x
  539. kPEFRelocLgByImport                EQU        $52                    ; Binary: 101_001x
  540. kPEFRelocLgRepeat                EQU        $58                    ; Binary: 101_100x
  541. kPEFRelocLgSetOrBySection        EQU        $5A                    ; Binary: 101_101x
  542. kPEFRelocUndefinedOpcode        EQU        $FF                    ; Used in masking table for all undefined values.
  543.  
  544. ;  ----------------------------------------------------------------------------    
  545. ;  The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode    
  546. ;  beyond the 7 used by the dispatch table.  To be precise it has 6 plus 4 but    
  547. ;  the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra    
  548. ;  subopcode bits.                                                                
  549.  
  550. kPEFRelocLgBySectionSubopcode    EQU        $00                    ; Binary: 0000
  551. kPEFRelocLgSetSectCSubopcode    EQU        $01                    ; Binary: 0001
  552. kPEFRelocLgSetSectDSubopcode    EQU        $02                    ; Binary: 0010
  553.  
  554. ;  -------------------------------------------------------------------------------------------- 
  555. ;  The initial values for the opcode "masking" table.  This has the enumeration values from        
  556. ;  above with appropriate replications for "don't care" bits.  It is almost certainly shorter    
  557. ;  and faster to look up the masked value in a table than to use a branch tree.                    
  558.  
  559. ;  =========================================================================================== 
  560. ;  RelocBySectDWithSkip Instruction 
  561. ;  -------------------------------- 
  562.  
  563. ;  -------------------------------------------------------------------------------------------- 
  564. ;  The "RelocBySectDWithSkip" instruction has the following bit field layout.                    
  565. ;                                                                                                  
  566. ;                              1         1                                                        
  567. ;          0 1 2             9 0         5                                                        
  568. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  569. ;         |0 0| skip count    | rel count |                                                        
  570. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  571. ;         | 2 |<-- 8 bits --->|<--  6 --->|                                                        
  572. ;                                                                                                  
  573. ;  ! Note that the stored skip count and reloc count are the actual values!                        
  574.  
  575. kPEFRelocWithSkipMaxSkipCount    EQU        255
  576. kPEFRelocWithSkipMaxRelocCount    EQU        63
  577.  
  578. ;  =========================================================================================== 
  579. ;  RelocRun Group 
  580. ;  -------------- 
  581.  
  582. ;  -------------------------------------------------------------------------------------------- 
  583. ;  The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            
  584. ;  "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        
  585. ;  following bit field layout.                                                                    
  586. ;                                                                                                  
  587. ;                                        1                                                        
  588. ;          0   2 3     6 7               5                                                        
  589. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  590. ;         |0 1 0| subop.| run length      |                                                        
  591. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  592. ;         |  3  |<- 4 ->|<-- 9 bits ----->|                                                        
  593. ;                                                                                                  
  594. ;  ! Note that the stored run length is the actual value minus 1, but the macros deal with the    
  595. ;  ! actual value!                                                                                
  596.  
  597. kPEFRelocRunMaxRunLength        EQU        512
  598.  
  599. ;  =========================================================================================== 
  600. ;  RelocSmIndex Group 
  601. ;  ------------------ 
  602.  
  603. ;  ----------------------------------------------------------------------------------------    
  604. ;  The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                
  605. ;  "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    
  606. ;  field layout.                                                                            
  607. ;                                                                                              
  608. ;                                        1                                                    
  609. ;          0   2 3     6 7               5                                                    
  610. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    
  611. ;         |0 1 1| subop.| index           |                                                    
  612. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    
  613. ;         |  3  |<- 4 ->|<-- 9 bits ----->|                                                    
  614. ;                                                                                              
  615. ;  ! Note that the stored index is the actual value!                                        
  616.  
  617. kPEFRelocSmIndexMaxIndex        EQU        511
  618.  
  619. ;  =========================================================================================== 
  620. ;  RelocIncrPosition Instruction 
  621. ;  ----------------------------- 
  622.  
  623. ;  -------------------------------------------------------------------------------------------- 
  624. ;  The "RelocIncrPosition" instruction has the following bit field layout.                        
  625. ;                                                                                                  
  626. ;                                        1                                                        
  627. ;          0     3 4                     5                                                        
  628. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  629. ;         |1 0 0 0| offset                |                                                        
  630. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  631. ;         |<- 4 ->|<-- 12 bits ---------->|                                                        
  632. ;                                                                                                  
  633. ;  ! Note that the stored offset is the actual value minus 1, but the macros deal with the        
  634. ;  ! actual value!                                                                                
  635.  
  636. kPEFRelocIncrPositionMaxOffset    EQU        4096
  637.  
  638. ;  =========================================================================================== 
  639. ;  RelocSmRepeat Instruction 
  640. ;  ------------------------- 
  641.  
  642. ;  -------------------------------------------------------------------------------------------- 
  643. ;  The "RelocSmRepeat" instruction has the following bit field layout.                            
  644. ;                                                                                                  
  645. ;                                        1                                                        
  646. ;          0     3 4     7 8             5                                                        
  647. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  648. ;         |1 0 0 1| chnks | repeat count  |                                                        
  649. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        
  650. ;         |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        
  651. ;                                                                                                  
  652. ;  ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    
  653. ;  ! macros deal with the actual values!                                                        
  654.  
  655. kPEFRelocSmRepeatMaxChunkCount    EQU        16
  656. kPEFRelocSmRepeatMaxRepeatCount    EQU        256
  657.  
  658. ;  =========================================================================================== 
  659. ;  RelocSetPosition Instruction 
  660. ;  ---------------------------- 
  661.  
  662. ;  -------------------------------------------------------------------------------------------- 
  663. ;  The "RelocSetPosition" instruction has the following bit field layout.                        
  664. ;                                                                                                  
  665. ;                                        1                                   1                    
  666. ;          0         5 6                 5     0                             5                    
  667. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  668. ;         |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    
  669. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  670. ;         |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    
  671. ;                                                                                                  
  672. ;  ! Note that the stored offset is the actual value!                                            
  673.  
  674. kPEFRelocSetPosMaxOffset        EQU        $03FFFFFF            ; 67,108,863
  675.  
  676. ;  =========================================================================================== 
  677. ;  RelocLgByImport Instruction 
  678. ;  --------------------------- 
  679.  
  680. ;  -------------------------------------------------------------------------------------------- 
  681. ;  The "RelocLgByImport" instruction has the following bit field layout.                        
  682. ;                                                                                                  
  683. ;                                        1                                   1                    
  684. ;          0         5 6                 5     0                             5                    
  685. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  686. ;         |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    
  687. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  688. ;         |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    
  689. ;                                                                                                  
  690. ;  ! Note that the stored offset is the actual value!                                            
  691.  
  692. kPEFRelocLgByImportMaxIndex        EQU        $03FFFFFF            ; 67,108,863
  693.  
  694. ;  =========================================================================================== 
  695. ;  RelocLgRepeat Instruction 
  696. ;  ------------------------- 
  697.  
  698. ;  -------------------------------------------------------------------------------------------- 
  699. ;  The "RelocLgRepeat" instruction has the following bit field layout.                            
  700. ;                                                                                                  
  701. ;                              1         1                                   1                    
  702. ;          0         5 6     9 0         5     0                             5                    
  703. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  704. ;         |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    
  705. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  706. ;         |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    
  707. ;                                                                                                  
  708. ;  ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        
  709. ;  ! the actual value!  The stored repeat count is the actual value!                            
  710.  
  711. kPEFRelocLgRepeatMaxChunkCount    EQU        16
  712. kPEFRelocLgRepeatMaxRepeatCount    EQU        $003FFFFF            ; 4,194,303
  713.  
  714. ;  =========================================================================================== 
  715. ;  RelocLgSetOrBySection Group 
  716. ;  --------------------------- 
  717.  
  718. ;  -------------------------------------------------------------------------------------------- 
  719. ;  The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    
  720. ;  "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        
  721. ;  field layout.                                                                                
  722. ;                                                                                                  
  723. ;                              1         1                                   1                    
  724. ;          0         5 6     9 0         5     0                             5                    
  725. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  726. ;         |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    
  727. ;         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    
  728. ;         |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    
  729. ;                                                                                                  
  730. ;  ! Note that the stored index is the actual value!                                            
  731.  
  732. kPEFRelocLgSetOrBySectionMaxIndex EQU    $003FFFFF            ; 4,194,303
  733.  
  734.  
  735.     ENDIF ; __PEFBINARYFORMAT__ 
  736.  
  737.